package cn.jietuo.juc.c_009_interview2;

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author zhangx & jietuo_zx@163.com
 * @version 1.0
 * @date 2020/5/8
 * @description:
 */
public class T03_MyContainer2<T> {

    private final static int MAX = 10;

    private int count = 0;

    private LinkedList<T> data = new LinkedList<>();

    private Lock lock = new ReentrantLock();
    Condition producer = lock.newCondition();
    Condition consumer = lock.newCondition();


    public void put(T t) {
        try {
            lock.lock();
            while (data.size() == MAX) {
                producer.await();
            }
            data.add(t);
            ++count;
            consumer.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public T get() {
        try {
            lock.lock();
            while (data.size() <= 0) {
                consumer.await();
            }
            T t = data.removeFirst();
            --count;
            producer.signalAll();
            return t;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return null;
    }


    public synchronized int getCount() {
        return count;
    }

    public static void main(String[] args) {
        T03_MyContainer2<String> myContainer = new T03_MyContainer2<>();

        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 10; j++) {
                    String s = myContainer.get();
                    System.out.println(Thread.currentThread().getName() + "，获取到数据：" + s);
                }

            }, "customer" + i).start();
        }

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                for (int j = 0; j < 20; j++) {
                    myContainer.put(Thread.currentThread().getName() + "--" + j);
                    System.out.println(Thread.currentThread().getName() + "，添加数据：" + Thread.currentThread().getName() + "--" + j);
                }
            }, "producer" + i).start();
        }
    }

}
